﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Web;
using _5E.Utils.CollectionHelper;

namespace WholesaleOnline.Controller
{
    public class SessionCache
    {
        public const string LOGIN_ID = "LoginId";
        private const string SESSION_COOKIE = "xm_0890_com";
        private static Dictionary<string, IGenericCache> m_cache = new Dictionary<string, IGenericCache>();
        private static Timer s_timer = null;
        private static object s_mutex = new object();
        private static SessionCache s_instance = new SessionCache();

        string Token { get { return HasToken ? HttpContext.Current.Request.Cookies[SESSION_COOKIE].Value : string.Empty; } }

        bool HasToken { get { return null != HttpContext.Current.Request.Cookies[SESSION_COOKIE]; } }

        string NewToken { get { return Guid.NewGuid().ToString().Replace("-", ""); } }

        public static IGenericCache Current { get { return s_instance.GetCurrentCache(); } }

        public static bool IsLogin { get { return Current.ContainsKey<Guid>(LOGIN_ID); } }

        public static Guid LognID { get { return Current.GetValue<Guid>(LOGIN_ID); } }

        static SessionCache()
        {
            s_timer = new Timer(state =>
            {
                if (3 != DateTime.Now.Hour)
                    return;
                lock (s_mutex)
                {
                    IEnumerable<string> timeoutTokens = m_cache.Where(item => (item.Value as MySession).IsTimeout)
                        .Select(item => item.Key);
                    foreach (var token in timeoutTokens)
                    {
                        m_cache.Remove(token);
                    }
                }
            }, null, 0, 1000 * 60 * 60);
        }

        public IGenericCache GetCurrentCache()
        {
            IGenericCache session;
            if (HasToken)
            {
                if (m_cache.TryGetValue(Token, out session))
                {
                    MySession mySession = session as MySession;
                    if (mySession.IsTimeout)
                        session.Clear();
                    else
                        mySession.Reset();
                    return session;
                }
                else
                {
                    HttpContext.Current.Response.Cookies.Remove(Token);
                }
            }
            string newToken = NewToken;
            session = new MySession();
            m_cache.Add(newToken, session);
            HttpContext.Current.Response.Cookies.Add(new HttpCookie(SESSION_COOKIE, newToken));
            return session;
        }
    }
}
